package com.iss.card.view.store;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import com.iss.card.R;
import com.iss.card.common.ApplicationManager;
import com.iss.card.common.CommonValue;
import com.iss.card.common.FunctionUtil;
import com.iss.card.common.IBackKeyListener;
import com.iss.card.common.Tools;
import com.iss.card.mapv2.GoogleMapView;
import com.iss.card.mapv2.MyLocationManager;
import com.iss.card.model.StoreAddressInfo;
import com.iss.card.model.StoreTypeInfo;
import com.iss.card.view.ContainerActivity;
import com.iss.card.view.model.ResponseBean;
import com.iss.card.view.overrideview.IOnClickEventListener;
import com.iss.card.webservice.BaseModel;
import com.iss.card.webservice.WebServiceAsyncService;
import com.iss.card.webservice.WebServiceAsyncService.Operation;
import com.iss.card.webservice.WebServiceAsyncService.PostExecute;
import com.iss.card.webservice.WebServiceAsyncServiceHelper;
import com.iss.card.webservice.WebServiceManager.WebServiceRegistrationParameter;
import com.iss.card.webservice.WebServiceManager.WebServiceUrlPortManager;
import com.iss.card.webservice.WebServiceUtils;

public class StoreFilterFragment extends Fragment implements IBackKeyListener {
	private static final String TAG = StoreFilterFragment.class.getSimpleName();
	private final static String SEARCH_RADIUS = "10";
	private final static String TYPE_ID = "type_id";
	private final static String TYPE_NAME = "type_name";

	private Context mContext;
	private ListView mLVTypeList;
	private List<StoreTypeInfo> mTypes;
	private List<StoreAddressInfo> mRoundStores = new ArrayList<StoreAddressInfo>();
	private IOnClickEventListener mStoreFilterViewClickEventListener;

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		mContext = activity;
		Log.e(TAG, "onAttach:");
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		Log.e(TAG, "onCreateView:");
		View v = (LinearLayout) inflater.inflate(
				R.layout.frame_store_filter_view1, null);
		initFragment(v);
		return v;
	}

	@Override
	public void onPause() {
		super.onPause();
		Log.e(TAG, "onPause:");
	}

	@Override
	public void onStart() {
		super.onStart();
		Log.e(TAG, "onStart:");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.support.v4.app.Fragment#onHiddenChanged(boolean)
	 */
	@Override
	public void onHiddenChanged(boolean hidden) {
		super.onHiddenChanged(hidden);
		Log.d(TAG, "onHiddenChanged: " + hidden);
	}

	@Override
	public void onResume() {
		super.onResume();
		Log.e(TAG, "onResume");
	}

	@Override
	public void onDestroyView() {
		super.onDestroyView();
		Log.e(TAG, "onDestroyView");
	}

	@Override
	public void onDestroy() {
		super.onDestroy();

	}

	public void setOnClickEventListener(IOnClickEventListener l) {
		mStoreFilterViewClickEventListener = l;
	}

	/**
	 * it will be invoked while this fragment is scroll to the front.
	 */
	public void onScrollToFront() {
		Log.d(TAG, "onScrollToFront");
		StoreTypeInfo info = FunctionUtil.getSelectedStoreType();
		TypeAdapter a = (TypeAdapter) mLVTypeList.getAdapter();
		if (a == null) {
			return;
		}
		a.setCurrentSelectedItem(info);
	}

	private void initFragment(View v) {
		mTypes = new ArrayList<StoreTypeInfo>();
		mLVTypeList = (ListView) v.findViewById(R.id.store_type_list);

		// prepare for utility items.
		ListView utilityList = (ListView) v
				.findViewById(R.id.store_utility_list);
		ArrayList<Map<String, String>> utilities = new ArrayList<Map<String, String>>();
		Map<String, String> randStore = new HashMap<String, String>();
		randStore.put(TYPE_NAME,
				mContext.getResources().getString(R.string.more_shake));
		utilities.add(randStore);

		Map<String, String> roundStore = new HashMap<String, String>();
		roundStore.put(TYPE_NAME,
				mContext.getResources().getString(R.string.more_around_shop));
		utilities.add(roundStore);
		utilityList.setAdapter(new SimpleAdapter(mContext, utilities,
				R.layout.store_filter_type_item, new String[] { TYPE_NAME },
				new int[] { R.id.tv_type_name }));
		utilityList
				.setOnItemClickListener(new AdapterView.OnItemClickListener() {
					@Override
					public void onItemClick(AdapterView<?> parent, View v,
							int position, long id) {
						if (mStoreFilterViewClickEventListener != null) {
							mStoreFilterViewClickEventListener
									.onClickItemInList();
						}

						String itemName = ((TextView) v
								.findViewById(R.id.tv_type_name)).getText()
								.toString();
						if (itemName.equals(mContext.getResources().getString(
								R.string.more_around_shop))) {
							// round store.
							Location current = MyLocationManager.instance()
									.getCurrentPosition();
							requestGetRoundStoreList(current.getLongitude(),
									current.getLatitude());
						} else if (itemName.equals(mContext.getResources()
								.getString(R.string.more_shake))) {
							// random store.
							Intent intent = new Intent(mContext,
									ContainerActivity.class);
							intent.putExtra(ApplicationManager.INTENT_KEY,
									ApplicationManager.INTENT_FRAGMENT_SHAKE);
							mContext.startActivity(intent);
						}
					}
				});

		requestGetStoreTypeInfo();
	}

	private void requestGetStoreTypeInfo() {
		WebServiceAsyncService service = new WebServiceAsyncService();
		service.setParameterToAsyncService(
				mContext,
				service.getNextToken(),
				Operation.OP_SERVICE_ARG_GET_STORE_TYPE_BY_CATEGORY,
				WebServiceRegistrationParameter.PARAMETERS_GET_TYPE_BY_CATEGORY,
				new String[] { "StoreType" },
				WebServiceUrlPortManager.ACTION_URL_PORT_GET_TYPE_BY_CATEGORY,
				this, WebServiceAsyncServiceHelper.TYPE_HTTP_GET_INSTREAM);

		service.setPostExecute(new PostExecute() {
			@Override
			public void onAsyncServiceComplete(int token, Object result,
					int index) {
				responseGetStoreTypeInfo(result);
			}
		});
	}

	private void responseGetStoreTypeInfo(Object result) {
		ResponseBean response = WebServiceUtils.getObjectResultToBaseInfo(
				result, StoreTypeInfo.class);
		if (Tools.onPostCheck(mContext, response)) {
			return;
		}

		List<? extends BaseModel> list = response.getReturnList();
		mTypes.clear();
		StoreTypeInfo all = new StoreTypeInfo();
		all.setTypeId(CommonValue.STORE_TYPE_ID_ALL);
		all.setTypeName(mContext.getResources()
				.getText(R.string.store_list_view_type_all).toString());
		mTypes.add(all);
		for (BaseModel info : list) {
			mTypes.add((StoreTypeInfo) info);
		}

		mLVTypeList.setAdapter(new TypeAdapter(mContext, mTypes));
		mLVTypeList
				.setOnItemClickListener(new AdapterView.OnItemClickListener() {

					@Override
					public void onItemClick(AdapterView<?> parent, View v,
							int position, long id) {
						StoreTypeInfo info = mTypes.get(position);
						FunctionUtil.setSelectedStoreTypeInfo(info);
						if (mStoreFilterViewClickEventListener != null) {
							mStoreFilterViewClickEventListener
									.onClickItemInList();
						}
					}

				});
	}

	private void requestGetRoundStoreList(double longitude, double latitude) {
		Log.i(TAG, "requestGetRoundStoreList:[" + longitude + "," + latitude
				+ "]");
		WebServiceAsyncService service = new WebServiceAsyncService();
		service.setParameterToAsyncService(
				mContext,
				service.getNextToken(),
				Operation.OP_SERVICE_ARG_NEAR_STORE,
				WebServiceRegistrationParameter.PRODUCT_NEAR_STORE,
				new String[] { String.valueOf(latitude),
						String.valueOf(longitude), SEARCH_RADIUS },
				WebServiceUrlPortManager.ACTION_URL_PORT_NEAR_STORE, this,
				WebServiceAsyncServiceHelper.TYPE_HTTP_GET_INSTREAM);

		service.setPostExecute(new PostExecute() {
			@Override
			public void onAsyncServiceComplete(int token, Object result,
					int index) {
				ResponseBean response = WebServiceUtils
						.getObjectResultToBaseInfo(result,
								StoreAddressInfo.class);
				if (Tools.onPostCheck(mContext, response)) {
					return;
				}
				mRoundStores.clear();
				List<? extends BaseModel> list = response.getReturnList();
				for (BaseModel info : list) {
					Log.d(TAG,
							"info: "
									+ ((StoreAddressInfo) info)
											.getStoreLatitude()
									+ ", "
									+ ((StoreAddressInfo) info)
											.getStoreLongitude());
					mRoundStores.add((StoreAddressInfo) info);
				}
				Log.d(TAG, "requestGetRoundStoreList: " + mRoundStores.size());

				goToMapView();
			}
		});
	}

	private void goToMapView() {
		StoreAddressInfo home = new StoreAddressInfo();
		Location current = MyLocationManager.instance().getCurrentPosition();
		home.setStoreLatitude(current.getLatitude());
		home.setStoreLongitude(current.getLongitude());
		home.setStoreName("Current Position");
		mRoundStores.add(0, home);
		Intent intent = new Intent(mContext, GoogleMapView.class);
		intent.putExtra(ApplicationManager.KEY_GMAP_MAP_VIEW_MODE,
				CommonValue.EnumGoogleMapviewMode.EGMViewRoundStore);
		intent.putExtra(ApplicationManager.KEY_GMAP_POSITION_DATA,
				(Serializable) mRoundStores);
		((FragmentActivity) mContext).startActivity(intent);
	}

	@Override
	public void cancelUpdate(Object... params) {
		// TODO Auto-generated method stub

	}

	private final class TypeAdapter extends BaseAdapter {
		private List<StoreTypeInfo> mContents = new ArrayList<StoreTypeInfo>();
		private int mCurrentSelectedPosition = -1;
		private Context mContext;

		public TypeAdapter(Context ct, List<StoreTypeInfo> data) {
			mContext = ct;
			mContents.clear();
			mContents.addAll(data);
		}

		/**
		 * set current selected item information. it will change the selected
		 * item's background color.
		 * 
		 * @param info
		 *            selected type information.
		 */
		public void setCurrentSelectedItem(StoreTypeInfo info) {
			int position = -1;
			if (CommonValue.STORE_TYPE_ID_ALL.equals(info.getTypeId())) {
				position = 0;
			} else {
				final int num = mTypes.size();
				for (int i = 0; i < num; ++i) {
					StoreTypeInfo s = mTypes.get(i);
					if (s.getTypeId().equals(info.getTypeId())) {
						position = i;
						break;
					}
				}
			}
			mCurrentSelectedPosition = position;
			this.notifyDataSetInvalidated();
		}

		@Override
		public int getCount() {
			return mContents.size();
		}

		@Override
		public Object getItem(int position) {
			return mContents.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder = null;
			if (convertView == null) {
				holder = new ViewHolder();
				convertView = LayoutInflater.from(this.mContext).inflate(
						R.layout.store_filter_type_item, null);
				holder.mTVTypeName = (TextView) convertView
						.findViewById(R.id.tv_type_name);
				convertView.setTag(holder);
			}

			holder = (ViewHolder) convertView.getTag();
			holder.mTVTypeName.setText(mContents.get(position).getTypeName());
			if (mCurrentSelectedPosition == position) {
				convertView.setBackgroundColor(mContext.getResources()
						.getColor(R.color.type_selected_in_type_list));
			} else {
				convertView.setBackgroundColor(Color.TRANSPARENT);
			}
			return convertView;
		}

		private final class ViewHolder {
			public TextView mTVTypeName;
		}
	}
}
